/****************************************************
	文件：HTDriver.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2021/1/1 13:21:57
	功能：框架启动器（入口）
*****************************************************/

using System;
using System.Collections.Generic;
using UnityEngine;
using HTFW.Consts;
using HTFW.Logger;
using HTFW.Res;
using HTFW.Scene;
using HTFW.Scheme;
using HTFW.UI;
using HTFW.Utility;
using HTFW.Utility.Global;

namespace HTFW.Core
{
    public class HTDriver : IInitializable, IDisposable, ILogicUpdate, IViewUpdate, ITimerUpdate, ILateUpdate
    {
        List<IService> mServiceLst; //框架服务列表
        List<IManager> mManagerLst; //框架管理器列表
        List<ILogicUpdate> mLogicUpdateLst; //逻辑帧列表
        List<IViewUpdate> mViewUpdateLst; //表现帧列表
        List<ITimerUpdate> mTimerUpdateLst; //计时任务帧列表
        List<ILateUpdate> mLateUpdateLst; //尾帧列表

        MonoBehaviour mMono;
        LogService mLogSvc; //日志打印
        TIDService mTIDSvc; //全局ID生成器

        CoroutineService mCoroSvc; //协程

        //TimerService mTimerSvc; //计时器
        ResService mResSvc; //资源加载
        AttributeService mAttributeSvc; //自定义属性

        static UnitContext mGlobalContext; //全局 上下文

        SchemeManager mSchemeMgr; //配置表 管理器
        UIManager mUIMgr; //UI 管理器
        SceneManager mSceneMgr; //场景 管理器
        ContextManager mContextMgr; //上下文 管理器

        /// <summary>
        /// 全局 上下文
        /// </summary>
        public static UnitContext GlobalContext => mGlobalContext;

        public HTDriver(MonoBehaviour mono)
        {
            mMono = mono;
            mServiceLst = new List<IService>();
            mManagerLst = new List<IManager>();
            mLogicUpdateLst = new List<ILogicUpdate>();
            mViewUpdateLst = new List<IViewUpdate>();
            mTimerUpdateLst = new List<ITimerUpdate>();
            mLateUpdateLst = new List<ILateUpdate>();
        }

        //--------------------  生命周期  --------------------//

        #region 生命周期

        /// <summary>
        /// 框架初始化
        /// </summary>
        public void Init(params object[] args)
        {
            //TODO 框架初始化：

            InitServices();
            InitManagers();
            InitGlobalContexts();

            InitLogicUpdates();
            InitViewUpdates();
            InitTimerUpdates();
            InitLateUpdates();
        }

        /// <summary>
        /// 框架销毁（销毁的顺序一般和初始化顺序相反）
        /// </summary>
        public void Dispose()
        {
            DisposeGlobalContexts();
            DisposeManagers();
            DisposeServices();

            mServiceLst = null;
            mManagerLst = null;
            mLogicUpdateLst = null;
            mViewUpdateLst = null;
            mTimerUpdateLst = null;
            mLateUpdateLst = null;
        }

        /// <summary>
        /// 逻辑帧
        /// </summary>
        public void OnLogicUpdate()
        {
            if (mLogicUpdateLst.IsNullOrEmpty()) return;

            foreach (var logic in mLogicUpdateLst)
                logic.OnLogicUpdate();
        }

        /// <summary>
        /// 表现帧
        /// </summary>
        public void OnViewUpdate()
        {
            if (mViewUpdateLst.IsNullOrEmpty()) return;

            foreach (var view in mViewUpdateLst)
                view.OnViewUpdate();
        }

        /// <summary>
        /// 执行计时任务的帧函数
        /// </summary>
        public void OnTimerUpdate()
        {
            if (mTimerUpdateLst.IsNullOrEmpty()) return;

            foreach (var timer in mTimerUpdateLst)
                timer.OnTimerUpdate();
        }

        /// <summary>
        /// 在框架内的尾帧执行
        /// </summary>
        public void OnLateUpdate()
        {
            if (mLateUpdateLst.IsNullOrEmpty()) return;

            foreach (var timer in mLateUpdateLst)
                timer.OnLateUpdate();
        }

        #endregion


        //--------------------  Service  --------------------//

        #region Service

        /// <summary>
        /// 初始化所有服务
        /// </summary>
        void InitServices()
        {
            mLogSvc = LogService.Instance;
            mLogSvc.Init();
            RegisterService(mLogSvc);

            mTIDSvc = TIDService.Instance;
            mTIDSvc.Init();
            RegisterService(mTIDSvc);

            mCoroSvc = CoroutineService.Instance;
            mCoroSvc.Init(mMono);
            RegisterService(mCoroSvc);

            // mTimerSvc = TimerService.Instance;
            // mTimerSvc.Init();
            // RegisterService(mTimerSvc);

            mResSvc = ResService.Instance;
            mResSvc.Init();
            RegisterService(mResSvc);

            mAttributeSvc = AttributeService.Instance;
            mAttributeSvc.Init();
            RegisterService(mAttributeSvc);
        }

        /// <summary>
        /// 销毁所有服务
        /// </summary>
        void DisposeServices()
        {
            foreach (var item in mServiceLst)
                item.Dispose();
        }

        #endregion


        //--------------------  Manager  --------------------//

        #region Manager

        /// <summary>
        /// 初始化所有管理器
        /// </summary>
        void InitManagers()
        {
            mContextMgr = ContextManager.Instance;
            mContextMgr.Init(mMono);
            RegisterManager(mContextMgr);

            mSchemeMgr = SchemeManager.Instance;
            mSchemeMgr.Init();
            RegisterManager(mSchemeMgr);

            mUIMgr = UIManager.Instance;
            mUIMgr.Init();
            RegisterManager(mUIMgr);

            mSceneMgr = SceneManager.Instance;
            mSceneMgr.Init(mMono);
            RegisterManager(mSceneMgr);
        }

        /// <summary>
        /// 销毁所有管理器
        /// </summary>
        void DisposeManagers()
        {
            foreach (var mgr in mManagerLst)
                mgr.Dispose();
        }

        #endregion


        //--------------------  Context  --------------------//

        #region Context

        /// <summary>
        /// 初始化所有上下文
        /// </summary>
        void InitGlobalContexts()
        {
            mGlobalContext = ContextManager.Instance.CreateContext<UnitContext>(ContextType.Unit, ContextScope.Global);

            mGlobalContext.Init(mMono);
        }

        /// <summary>
        /// 销毁所有上下文
        /// </summary>
        void DisposeGlobalContexts()
        {
            if (mGlobalContext != null)
            {
                ContextManager.Instance.DeleteContext(mGlobalContext);
                mGlobalContext = null;
            }
        }

        #endregion


        //--------------------  LogicUpdate  --------------------//

        #region LogicUpdate

        void InitLogicUpdates()
        {
            RegisterLogicUpdata(mLogSvc);
            //TODO add InitLogicUpdates
        }

        #endregion


        //--------------------  ViewUpdate  --------------------//

        #region ViewUpdate

        void InitViewUpdates()
        {
            RegisterViewUpdata(mUIMgr);
            //TODO add InitViewUpdates
        }

        #endregion


        //--------------------  TimerUpdate  --------------------//

        #region TimerUpdate

        void InitTimerUpdates()
        {
            //RegisterTimerUpdata(mTimerSvc);
            RegisterTimerUpdata(mContextMgr);
            //TODO add InitTimerUpdates
        }

        #endregion


        //--------------------  LateUpdate  --------------------//

        #region LateUpdate

        void InitLateUpdates()
        {
            RegisterLateUpdata(mTIDSvc);
            //TODO add InitLateUpdates
        }

        #endregion


        /// <summary>
        /// 注册服务
        /// </summary>
        void RegisterService(IService svc)
        {
            mServiceLst.Add(svc);
        }

        /// <summary>
        /// 注册管理器
        /// </summary>
        void RegisterManager(IManager mgr)
        {
            mManagerLst.Add(mgr);
        }

        void RegisterLogicUpdata(ILogicUpdate logicUpdate)
        {
            mLogicUpdateLst.Add(logicUpdate);
        }

        void RegisterViewUpdata(IViewUpdate viewUpdate)
        {
            mViewUpdateLst.Add(viewUpdate);
        }

        void RegisterTimerUpdata(ITimerUpdate timerUpdate)
        {
            mTimerUpdateLst.Add(timerUpdate);
        }

        void RegisterLateUpdata(ILateUpdate lateUpdate)
        {
            mLateUpdateLst.Add(lateUpdate);
        }

        /// <summary>
        /// 获取全局的 MonoBehaviour
        /// </summary>
        public MonoBehaviour GetGlobalMono()
        {
            return mMono;
        }
    }
}